parser grammar javaParser;

options {
  language = Java;
  tokenVocab = javaLexer;
}
@header {package PL.practica8;}

@members {
  private boolean breakFound = false;
  
  public boolean isBreakFound() { 
    return breakFound;
  } 
  
  ArrayList <RecognitionException> errores = new ArrayList<RecognitionException>();

  public boolean listaVacia (){
    if (errores.isEmpty()){
      return true;
    }else
      return false;
}

public ArrayList getListaErrores(){return errores;}


@Override
public void reportError (RecognitionException e){
  System.err.println (getErrorMessage(e, getTokenNames()));
  errores.add(e);
}
  
  
  
  
}


// -----------------------------------------------------------------------------
// Parser rules
// -----------------------------------------------------------------------------

//reglas para hacer mas legible las reglas MAS COMPLEJAS 
tipo : VOID | CHAR | FLOAT | INT;
parametro : CADENA | CARACTER | NUMERO | ID (ABRIRCORCHETES NUMERO CERRARCORCHETES)?;
parametros : parametro (COMA parametro)*;
def_parametros : tipo parametro (COMA tipo parametro)*;
op_arit : MAS|MENOS|SLASH|ASTERISCO;
op_log : OP_OR | OP_AND;



entrada : (metodo|sentencia[false])*;
 metodo : cabecerafuncion bloqueLlaves[false];
 asignacion :  declaracion  ((ASIGNACION (expr | llamadafuncion)) | (COMA declaracion))*;
 declaracion : tipo? ID ;

 expr : exp_mult ((MAS exp_mult) | (MENOS exp_mult))*;   
 exp_mult  :  exp_base((ASTERISCO exp_base) | (SLASH exp_base))* ;
 exp_base :  NUMERO | ABRIRPARENTESIS expr CERRARPARENTESIS | ID;
 
cabecerafuncion : tipo ID ABRIRPARENTESIS def_parametros? CERRARPARENTESIS;

llamadafuncion : ID ABRIRPARENTESIS parametros? CERRARPARENTESIS;

sentencia [boolean dentrowhile] : (llamadafuncion
            | BREAK {if (dentrowhile== true) breakFound = true;}
            | asignacion 
            | ret) SEPARADOR 
            | buclewhile [dentrowhile]
            |condicionif [dentrowhile];

bloqueLlaves[boolean dentrowhile] : ABRIRLLAVE  sentencia[dentrowhile]+  CERRARLLAVE;


buclewhile[boolean dentrowhile] : WHILE ABRIRPARENTESIS cond CERRARPARENTESIS (sentencia[true]| bloqueLlaves[true]);
condicionif[boolean dentrowhile] : IF  ABRIRPARENTESIS cond CERRARPARENTESIS (sentencia[dentrowhile]| bloqueLlaves[dentrowhile]);
		cond : (OP_NOT)? cond_expr (op_log (OP_NOT)? cond_expr)*;
		cond_expr : expr (OP_COMP expr)*;
ret : RETORNAR parametro ;
//arithmethic_if : cond_expr INTERROGACION expr DOSPUNTOS expr;

